package com.bingxue.edu.management.shop.service;

import com.bingxue.edu.common.enums.ChangeTypeEnum;
import com.bingxue.edu.common.enums.ClassCategoryEnum;
import com.bingxue.edu.framework.common.model.PageQuery;
import com.bingxue.edu.framework.mybatis.base.BaseService;
import com.bingxue.edu.management.education.mapper.EnrollChangeRecordMapper;
import com.bingxue.edu.management.education.model.entity.ClassInfo;
import com.bingxue.edu.management.education.model.entity.EnrollChangeRecord;
import com.bingxue.edu.management.education.model.entity.Enrollment;
import com.bingxue.edu.management.education.service.ClassInfoService;
import com.bingxue.edu.management.education.service.LessonStudentService;
import com.bingxue.edu.management.shop.mapper.SellRecordMapper;
import com.bingxue.edu.management.shop.model.entity.OrderItem;
import com.bingxue.edu.management.shop.model.entity.Refund;
import com.bingxue.edu.management.shop.model.entity.SellRecord;
import com.bingxue.edu.management.shop.model.query.SellRecordQuery;
import com.bingxue.edu.management.shop.model.query.SellRecordStatsQuery;
import com.bingxue.edu.management.shop.model.resp.SellRecordResp;
import com.bingxue.edu.management.shop.model.resp.SellRecordStatsResp;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.bingxue.edu.management.education.model.entity.table.ClassInfoTableDef.CLASS_INFO;
import static com.bingxue.edu.management.education.model.entity.table.EnrollChangeRecordTableDef.ENROLL_CHANGE_RECORD;
import static com.bingxue.edu.management.shop.model.entity.table.SellRecordTableDef.SELL_RECORD;
import static com.bingxue.edu.management.system.model.entity.table.EmployeeTableDef.EMPLOYEE;

/**
 * 销售顾问业绩Service
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SellRecordService extends BaseService<SellRecordMapper, SellRecord> {

    private final ClassInfoService classInfoService;
    private final OrderItemService orderItemService;
    private final LessonStudentService lessonStudentService;
    private final EnrollChangeRecordMapper enrollChangeRecordMapper;

    public Page<SellRecordResp> getSellRecordPage(SellRecordQuery query, PageQuery pageQuery) {
        QueryWrapper queryWrapper = buildQueryWrapper(query);
        return this.getMapper().paginateWithRelationsAs(pageQuery.toPage(), queryWrapper, SellRecordResp.class);
    }

    /**
     * 查询销售顾问业绩信息列表
     * @param query 查询条件
     */
    public List<SellRecordResp> getSellRecordList(SellRecordQuery query) {
        QueryWrapper queryWrapper = buildQueryWrapper(query);
        return this.getMapper().selectListWithRelationsByQueryAs(queryWrapper, SellRecordResp.class);
    }

    private QueryWrapper buildQueryWrapper(SellRecordQuery query) {
        return QueryWrapper.create()
                .select(SELL_RECORD.ALL_COLUMNS,
                        CLASS_INFO.SUBJECT.as(SellRecordResp::getSubject),
                        CLASS_INFO.CLASS_YEAR.as(SellRecordResp::getClassYear),
                        CLASS_INFO.TERM.as(SellRecordResp::getTerm),
                        CLASS_INFO.GRADE.as(SellRecordResp::getGrade),
                        CLASS_INFO.NAME.as(SellRecordResp::getClassName))
                .from(SELL_RECORD)
                .leftJoin(CLASS_INFO).on(CLASS_INFO.ID.eq(SELL_RECORD.CLASS_ID))
                .where(SELL_RECORD.SELLER_ID.in(query.getSellerId()))
                    .and(SELL_RECORD.BUSINESS_TIME.ge(query.getStartDate()))
                    .and(SELL_RECORD.BUSINESS_TIME.lt(query.getEndDate()))
                    .and(SELL_RECORD.VALID.eq(query.getValid()))
                    .and(ClassInfoService.buildCommonClassQueryCondition(query));
    }

    /**
     * 查询销售顾问业绩统计数据列表,包含各个科目的业绩数据
     */
    public List<SellRecordStatsResp> getSellRecordStats(SellRecordStatsQuery query) {
        //根据存在的科目动态返回科目数据
        //查询业绩统计数据
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(SELL_RECORD.SELLER_ID.as(SellRecordStatsResp::getSellerId),
                        EMPLOYEE.NAME.as(SellRecordStatsResp::getSellerName),
                        CLASS_INFO.SUBJECT.as(SellRecordStatsResp::getSubject),
                        QueryMethods.sum(SELL_RECORD.PERFORMANCE).as(SellRecordStatsResp::getPerformance))
                .from(SELL_RECORD)
                    .leftJoin(EMPLOYEE).on(EMPLOYEE.ID.eq(SELL_RECORD.SELLER_ID))
                    .leftJoin(CLASS_INFO).on(CLASS_INFO.ID.eq(SELL_RECORD.CLASS_ID))
                .where(SELL_RECORD.SELLER_ID.in(query.getSellerId()))
                    .and(SELL_RECORD.BUSINESS_TIME.ge(query.getStartDate()))
                    .and(SELL_RECORD.BUSINESS_TIME.le(query.getEndDate()))
                    .and(SELL_RECORD.VALID.eq(query.getValid()))
                    .and(ClassInfoService.buildCommonClassQueryCondition(query))
                .groupBy(SELL_RECORD.SELLER_ID, CLASS_INFO.SUBJECT);

        return this.listAs(queryWrapper, SellRecordStatsResp.class);
    }


    /**
     * 创建销售业绩记录
     * @param sellerId 销售顾问id
     */
    public void createEnrollSellRecord(Enrollment enrollment, String sellerId) {
        OrderItem orderItem = null;
        QueryWrapper queryWrapper = QueryWrapper.create()
                .from(ENROLL_CHANGE_RECORD)
                .where(ENROLL_CHANGE_RECORD.ENROLLMENT_ID.eq(enrollment.getId()))
                .and(ENROLL_CHANGE_RECORD.CHANGE_TYPE.eq(ChangeTypeEnum.NEW_ENROLL));
        EnrollChangeRecord changeRecord = enrollChangeRecordMapper.selectOneByQuery(queryWrapper);
        if (changeRecord != null && changeRecord.getBusinessId() != null) {
            orderItem = orderItemService.getById(changeRecord.getBusinessId());
        }
//        OrderItem orderItem = orderItemService.getByClassIdAndStudentId(enrollment.getClassId(), enrollment.getStudentId());
        this.createEnrollSellRecord(enrollment, orderItem, sellerId);
    }

    /**
     * 创建销售业绩记录
     */
    public void createEnrollSellRecord(Enrollment enrollment, OrderItem orderItem, String sellerId) {
        ClassInfo classInfo = classInfoService.getById(enrollment.getClassId());
        if(!ClassCategoryEnum.LONG_TERM_CLASS.equals(classInfo.getClassCategory())) {
            log.info("报名班级不为长期班, 跳过创建销售业绩. {}", classInfo.getId());
        }
        SellRecord oldSellRecord = this.getByEnrollmentId(enrollment.getId());
        if (oldSellRecord != null) {
            log.info("已创建销售业绩记录, 跳过. 报名id: {}", enrollment.getId());
            return;
        }
        SellRecord sellRecord = new SellRecord();
        sellRecord.setSellerId(sellerId);
        sellRecord.setEnrollmentId(enrollment.getId());
        sellRecord.setStudentId(enrollment.getStudentId());
        sellRecord.setClassId(classInfo.getId());
        sellRecord.setCampusId(classInfo.getCampusId());
        sellRecord.setPerformance(classInfo.getSalePerformanceFactor());
        sellRecord.setBusinessType(ChangeTypeEnum.NEW_ENROLL);
        if (orderItem != null) {
            sellRecord.setBusinessId(orderItem.getOrderId());
            sellRecord.setBusinessTime(orderItem.getCreateTime());
        } else {
            sellRecord.setBusinessTime(enrollment.getCreateTime());
        }
        sellRecord.setValid(!lessonStudentService.existLessonSignInRecord(enrollment.getStudentId(), classInfo.getSubject()));

        this.save(sellRecord);
        log.info("创建销售业绩成功: {}", sellRecord);
    }

    /**
     * 创建退班业绩记录
     */
    public void createCancelSellRecord(Enrollment enrollment, Refund refund) {
        ClassInfo classInfo = classInfoService.getById(enrollment.getClassId());
        SellRecord oldSellRecord = this.getByEnrollmentId(enrollment.getId());
        if (oldSellRecord == null) {
            log.info("没有设置销售业绩记录");
            return;
        }
        SellRecord sellRecord = new SellRecord();
        sellRecord.setSellerId(oldSellRecord.getSellerId());
        sellRecord.setEnrollmentId(enrollment.getId());
        sellRecord.setStudentId(enrollment.getStudentId());
        sellRecord.setClassId(classInfo.getId());
        sellRecord.setCampusId(classInfo.getCampusId());
        sellRecord.setPerformance(-classInfo.getSalePerformanceFactor());
        sellRecord.setBusinessType(ChangeTypeEnum.CANCEL_CLASS);
        sellRecord.setBusinessId(refund.getId());
        sellRecord.setBusinessTime(refund.getCreateTime());
        sellRecord.setValid(true);

        this.save(sellRecord);

        log.info("创建退班业绩成功:  {}", sellRecord);
    }

    /**
     * 根据报名id查询销售业绩记录
     */
    public SellRecord getByEnrollmentId(String enrollmentId) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(SELL_RECORD.ALL_COLUMNS)
                .from(SELL_RECORD)
                .where(SELL_RECORD.ENROLLMENT_ID.eq(enrollmentId))
                .and(SELL_RECORD.BUSINESS_TYPE.eq(ChangeTypeEnum.NEW_ENROLL));
        return this.getOne(queryWrapper);
    }

}
